<!--
 * @Author: rxn 1003312535@qq.com
 * @Date: 2024-07-05 15:25:53
 * @LastEditors: rxn 1003312535@qq.com
 * @LastEditTime: 2024-07-24 10:19:41
 * @FilePath: \vue3-progect\src\views\example\three\geometry\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!--生成曲线几何体-->
<template>
	<div id="three_container"></div>
	<el-button class="downLoadBtn" ref="downLoadBtn" @click="saveFile"
		>下载</el-button
	>
</template>

<script setup>
import * as THREE from "three";
import { onMounted, ref } from "vue";
//-
import { AxesHelper } from "../case/helper/AxesHelper";
//-
import { initContainer } from "../js/init";
import { onResize } from "../case/helper/onResize.js";

let scene, renderer, camera;
onMounted(() => {
	let container = document.getElementById("three_container");
	let instances = initContainer(THREE, container);
	scene = instances.scene;
	renderer = instances.renderer;
	camera = instances.camera;
	AxesHelper(THREE, scene);
	onResize(container, renderer, camera);
	const ambient = new THREE.AmbientLight("#ffffff");
	scene.add(ambient);
	demo();
	createSprite();
});
const animate = (renderer, scene, camera, raindrops, group) => {
	requestAnimationFrame(
		animate.bind(this, renderer, scene, camera, raindrops, group)
	);
	raindrops && updateRaindrop(raindrops);
	group && loop(group);
	renderer.render(scene, camera);
};
const demo = () => {
	const url = new URL("@/assets/image/map/location.png", import.meta.url).href;
	const iconURL = new THREE.TextureLoader().load(url);
	// const geometry1 = new THREE.BufferGeometry();
	const material1 = new THREE.SpriteMaterial({
		color: 0x00ff00,
		// rotation: 40
		map: iconURL
	});
	// 创建精灵模型对象，不需要几何体geometry参数
	const sprite = new THREE.Sprite(material1);
	sprite.scale.set(33.3, 33.3, 33.3);
	sprite.position.set(0, 50, 0);
	scene.add(sprite);
	// 创建下雨的系统
	var raindrops = [];
	for (var i = 0; i < 10; i++) {
		var system = createRaindrop();
		raindrops.push(system);
	}
	animate(renderer, scene, camera, raindrops, null);
	// console.log(iconURL, "iconURL", sprite);

	/**
	 * 下雨效果
	 */
};

const createRaindrop = () => {
	let geometry = new THREE.BufferGeometry();
	let material = new THREE.PointsMaterial({ size: 0.5, color: 0xffffff });
	let vertices = [];
	for (let i = 0; i < 20; i++) {
		let position = new THREE.Vector3(
			Math.random() * 100 - 1,
			Math.random() * 100 - 1,
			Math.random() * 100 - 1
		);
		vertices.push(position);
	}
	geometry.setFromPoints(vertices);
	let points = new THREE.Points(geometry, material);
	scene.add(points);
	return points;
};
/**
 * 更新雨滴位置
 * @param raindrops
 */
const updateRaindrop = (raindrops) => {
	raindrops.forEach(function (system) {
		// console.log(system.geometry.attributes.position);
		// 获取顶点位置数据
		const positionAttribute = system.geometry.attributes.position;

		// 创建一个数组来存储所有的顶点坐标
		const vertices = [];

		// 遍历位置数据，将坐标添加到数组中
		for (let i = 0; i < positionAttribute.count; i++) {
			const x = positionAttribute.getX(i);
			const y = positionAttribute.getY(i);
			const z = positionAttribute.getZ(i);
			vertices.push(new THREE.Vector3(x, y, z));
		}
		// console.log(vertices, "vertices");
		vertices.forEach((vertex) => {
			vertex.y -= 1; // 下降速度
			if (vertex.y < 0) vertex.y = 100; // 超出屏幕的重置
		});
		// console.log(vertices, "vertices==");
		system.geometry.setFromPoints(vertices);
		system.geometry.verticesNeedUpdate = true; // 更新顶点
	});
};

/**
 * 下载图片
 */
const downLoadBtn = ref(null);
const saveFile = () => {
	console.log(downLoadBtn, "downLoadBtn");
	const link = document.createElement("a");
	const canvas = renderer.domElement;
	link.href = canvas.toDataURL("image/png");
	link.download = "threejs.png";
	link.click();
};

/**
 * ===========================方法二
 */
const createSprite = () => {
	const group = new THREE.Group();
	const spriteMaterial = new THREE.SpriteMaterial({ color: 0xff0000 });

	for (let i = 0; i < 1000; i++) {
		const sprite = new THREE.Sprite(spriteMaterial);
		group.add(sprite);
		sprite.scale.set(1, 1, 1);
		const x = 1000 * (Math.random() - 0.5);
		const y = 600 * Math.random();
		const z = 1000 * (Math.random() - 0.5);
		sprite.position.set(x, y, z);
	}
	scene.add(group);
	animate(renderer, scene, camera, null, group);
};
// const clock = new THREE.Clock();
function loop(group) {
	// const t = clock.getDelta();
	group.children.forEach((sprite) => {
		// sprite.position.y -= t * 600; //值越大，下降速度越快
		sprite.position.y -= 3;
		if (sprite.position.y < 0) {
			sprite.position.y = 600;
		}
	});
}
</script>

<style lang="less" scoped>
#three_container {
	height: 100%;
}
.downLoadBtn {
	position: absolute;
	right: 0;
	top: 10px;
	z-index: 99;
}
</style>
